home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / lib / asm / file.s < prev    next >
Encoding:
Text File  |  1998-10-04  |  19.4 KB  |  962 lines

  1. ;
  2. ; file.s -- an ACE linked library module: file functions.
  3. ; Copyright (C) 1998 David Benn
  4. ; This program is free software; you can redistribute it and/or
  5. ; modify it under the terms of the GNU General Public License
  6. ; as published by the Free Software Foundation; either version 2
  7. ; of the License, or (at your option) any later version.
  8. ;
  9. ; This program is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License
  15. ; along with this program; if not, write to the Free Software
  16. ; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17. ;
  18. ; Author: David J Benn
  19. ;   Date: 3rd-30th November, 1st-13th December 1991,
  20. ;      20th, 23rd,25th-27th January 1992, 
  21. ;         2nd,4th,6th,12th-19th,21st-24th,29th February 1992,
  22. ;      1st,14th March 1992,
  23. ;      4th,7th,21st,22nd,26th April 1992,
  24. ;      2nd,3rd,5th,7th,8th,10th-17th May 1992,
  25. ;      6th,8th,11th,12th,28th,30th June 1992,
  26. ;      1st-3rd,13th,14th,18th-20th,22nd July 1992,
  27. ;      9th August 1992,
  28. ;      5th,21st December 1992,
  29. ;      5th,6th,12th January 1993,
  30. ;      7th,14th-16th,18th February 1993,
  31. ;      1st March 1993,
  32. ;      9th-11th May 1993,
  33. ;      10th June 1993,
  34. ;      26th September 1993,
  35. ;      19th March 1994,
  36. ;      10th April 1994,
  37. ;      13th May 1994,
  38. ;      10th,15th,17th March 1996
  39. ;
  40. ; registers d0-d6 and a0-a3 are modified by some of the following. BEWARE!
  41. ;
  42. ; a4,a5 are used by link/unlk.
  43. ; a6 is library base holder.
  44. ; a7 is stack pointer. 
  45. ; d7 is used for array index calculations.
  46. ;
  47.  
  48. ; error codes
  49. BFN    equ    52    ; Bad File Number
  50. BFM    equ    54    ; Bad File Mode
  51.  
  52. ; miscellaneous defines
  53. MAXSTRINGSIZE         equ     1024
  54. OFFSET_END        equ    1
  55. OFFSET_BEGINNING    equ    -1
  56. MODE_OLDFILE        equ    1005
  57. MODE_NEWFILE        equ    1006
  58. MODE_READWRITE        equ    1004
  59. ACCESS_READ        equ    -2    
  60.  
  61.     ; file routines
  62.     xdef    _openfile
  63.     xdef    _closefile
  64.  
  65.     xdef    _writeshort
  66.     xdef    _writelong
  67.     xdef    _writesingle
  68.     xdef    _writestring    ; WRITE# / PRINT#
  69.  
  70.     xdef    _fprintshort
  71.     xdef    _fprintlong
  72.     xdef    _fprintsingle    ; PRINT#
  73.  
  74.     xdef    _writecomma
  75.     xdef    _writequote
  76.     xdef    _write_eoln
  77.     xdef    _writeSPC
  78.     xdef    _writeTAB    ; WRITE# / PRINT# 
  79.  
  80.     xdef    _inputstrfromfile
  81.     xdef    _line_input
  82.  
  83.     xdef    _finputstring
  84.     xdef    _finputsingle
  85.     xdef    _finputshort
  86.     xdef    _finputlong    ; INPUT#
  87.  
  88.     xdef    _eoftest
  89.     xdef    _lof
  90.     xdef    _handle
  91.  
  92.     xdef    _kill
  93.     xdef    _rename
  94.     xdef    _chdir
  95.  
  96.        ; external references
  97.     xref    _shortfmt
  98.     xref    _longfmt
  99.     xref    _file_handle_list
  100.     xref    _line_end
  101.     xref    _quote_mark
  102.     xref    _comma
  103.     xref    _space
  104.     xref    _tab
  105.  
  106.     xref    _fileinpstring
  107.     xref    _filecharcount
  108.     xref    _tempfinp
  109.     xref    _fstrbuf
  110.     xref    _filenum
  111.     xref    _eofhandle
  112.     xref    _filesize
  113.     xref    _filehandle
  114.     xref    _oldfilepos
  115.     xref    _filespec_ptr
  116.  
  117.     xref    _error_code
  118.  
  119.     xref    _strlen
  120.     xref    _sprintf
  121.     xref    _fgetchars
  122.     xref    _fgetline
  123.     xref    _fgetseqfld
  124.     xref    _strshort
  125.     xref    _strlong
  126.     xref    _strsingle
  127.     xref    _val
  128.     xref    _short_from_string
  129.     xref    _long_from_string
  130.        xref      _LVOWrite
  131.     xref    _LVORead
  132.     xref    _LVOOpen
  133.     xref    _LVOClose
  134.     xref    _LVOSeek
  135.     xref    _LVODeleteFile
  136.     xref    _LVORename
  137.     xref    _LVOLock
  138.     xref    _LVOUnLock
  139.     xref    _LVOCurrentDir
  140.     xref    _LVOIoErr
  141.  
  142.       xref      _DOSBase    
  143.  
  144.     SECTION file_code,CODE
  145.  
  146. ; *** FILE ROUTINES ***
  147.  
  148. ;
  149. ; Ask DOS whether an error has occurred since the last I/O operation.
  150. ;
  151. _IoErr_poll:
  152.     move.l    d0,-(sp)
  153.  
  154.     cmpi.l    #0,d0
  155.     bgt.s    _quit_IoErr_poll  ; Last operation was successful
  156.  
  157.     ; Last operation was unsuccessful -> get error code
  158.     movea.l    _DOSBase,a6
  159.     jsr    _LVOIoErr(a6)
  160.     move.l    d0,_error_code
  161.  
  162. _quit_IoErr_poll:    
  163.     move.l    (sp)+,d0
  164.     rts
  165.  
  166. ;
  167. ; OPEN mode,[#]filenumber,filespec - open a file. 
  168. ;                   - a0=mode string; d0=filenumber; 
  169. ;                     a1=filespec string.
  170. ;
  171. _openfile:
  172.     jsr    _gencheckfilenum
  173.     cmpi.l    #-1,d0
  174.     bne.s    _get_filehandle
  175.     moveq    #0,d0
  176.     rts
  177.  
  178. _get_filehandle:
  179.     lsl.l    #2,d0        ; filenumber x 4.        
  180.     move.l    #_file_handle_list,d4
  181.     add.l    d0,d4        ; find start of long in list
  182.     move.l    d4,a3
  183.     cmpi.l    #0,(a3)
  184.     beq.s    _whichopenmode    ; if file handle not used -> continue
  185.  
  186.     move.l    #BFN,_error_code
  187.  
  188.     rts
  189.  
  190. _whichopenmode:
  191.     ; determine open mode
  192.     cmpi.b    #79,(a0)    ; "O" ?
  193.     beq.s    _openforoutput
  194.     cmpi.b    #111,(a0)    ; "o" ?
  195.     beq.s    _openforoutput
  196.     
  197.     cmpi.b    #73,(a0)    ; "I" ?
  198.     beq.s    _openforinput
  199.     cmpi.b    #105,(a0)    ; "i" ?
  200.     beq.s    _openforinput
  201.  
  202.      cmpi.b    #82,(a0)    ; "R" ?
  203.     beq.s    _openforrandom
  204.      cmpi.b    #114,(a0)    ; "r" ?
  205.     beq.s    _openforrandom
  206.  
  207.      cmpi.b    #65,(a0)    ; "A" ?
  208.     beq.s    _openforappend
  209.      cmpi.b    #97,(a0)    ; "a" ?
  210.     beq.s    _openforappend
  211.  
  212.     move.l    #BFM,_error_code
  213.  
  214.     rts
  215.  
  216. _openforoutput:
  217.     move.l    _DOSBase,a6
  218.     move.l    a1,d1            ; filespec
  219.     move.l    #MODE_NEWFILE,d2    ; create a new file
  220.     jsr    _LVOOpen(a6)
  221.     move.l    d0,(a3)            ; store file handle
  222.     jsr    _IoErr_poll
  223.     rts
  224.  
  225. _openforinput:
  226.     move.l    _DOSBase,a6
  227.     move.l    a1,d1            ; filespec
  228.     move.l    #MODE_OLDFILE,d2    ; open an existing file
  229.     jsr    _LVOOpen(a6)
  230.     move.l    d0,(a3)            ; store file handle
  231.     jsr    _IoErr_poll
  232.     rts
  233.  
  234. _openforrandom:
  235.     move.l    _DOSBase,a6
  236.     move.l    a1,d1            ; filespec
  237.     move.l    #MODE_READWRITE,d2    ; create a new file
  238.     jsr    _LVOOpen(a6)
  239.     move.l    d0,(a3)            ; store file handle
  240.     jsr    _IoErr_poll
  241.     rts
  242.  
  243. _openforappend:
  244.     move.l    _DOSBase,a6
  245.  
  246.     move.l    a1,_filespec_ptr    ; save filespec pointer
  247.  
  248.     move.l    a1,d1            ; filespec
  249.     move.l    #MODE_OLDFILE,d2    ; Test whether file exists
  250.     jsr    _LVOOpen(a6)
  251.     move.l    d0,(a3)            ; store file handle
  252.     
  253.     cmpi.l    #0,d0            ; if handle = NULL then  
  254.     bne.s    _seek_to_end_of_file    ; open a new file first
  255.                     ; else just seek to end 
  256.                     ; of existing file + 1 byte.
  257.  
  258.     move.l    _filespec_ptr,d1    ; filespec
  259.     move.l    #MODE_NEWFILE,d2    ; Create a new file    
  260.     jsr    _LVOOpen(a6)
  261.     move.l    d0,(a3)            ; store file handle
  262.     jsr    _IoErr_poll
  263.     
  264.     rts
  265.     
  266. _seek_to_end_of_file:
  267.     ; set file pointer to EOF
  268.     move.l    d0,d1            ; file handle
  269.     move.l    #0,d2            ; position=0 bytes from end
  270.     move.l    #1,d3            ; offset from end
  271.     jsr    _LVOSeek(a6)
  272.     jsr    _IoErr_poll
  273.  
  274.     rts
  275.         
  276. ;
  277. ; CLOSE [#]filenumber[,[#]filenumber..] - close a file. d0=filenumber.
  278. ;
  279. _closefile:
  280.     jsr    _gencheckfilenum
  281.     cmpi.l    #-1,d0
  282.     bne.s    _closefile_gethandlestore
  283.     moveq    #0,d0
  284.     rts
  285.  
  286. _closefile_gethandlestore:
  287.     lsl.l    #2,d0        ; filenumber x 4.        
  288.     move.l    #_file_handle_list,d4
  289.     add.l    d0,d4        ; find start of long in list
  290.     move.l    d4,a3
  291.     cmpi.l    #0,(a3)
  292.     bne.s    _close_the_file    ; if file handle is used -> continue
  293.     move.l    #BFN,_error_code
  294.     rts
  295.  
  296. _close_the_file:
  297.     movea.l    _DOSBase,a6
  298.     move.l    (a3),d1        ; file handle
  299.     jsr    _LVOClose(a6)
  300.  
  301.     ; zero the filehandle
  302.     move.l    #0,(a3)
  303.  
  304.     rts
  305.  
  306. ;
  307. ; write a short integer to a file. d0=filenumber. d1=short integer.
  308. ;
  309. _writeshort:
  310.     move.l    d0,_filenum    ; save filenumber
  311.  
  312.     ; convert short to a string
  313.     move.w    d1,-(sp)
  314.     pea    _shortfmt
  315.     move.l    #_fstrbuf,-(sp)
  316.     jsr    _sprintf
  317.     add.l    #10,sp
  318.  
  319.     lea    _fstrbuf,a0
  320.     move.l    _filenum,d0
  321.     jsr    _writestring    ; write to file
  322.  
  323.     rts
  324.  
  325. ;
  326. ; write a long integer to a file. d0=filenumber; d1=long integer.
  327. ;
  328. _writelong:
  329.     move.l    d0,_filenum    ; save filenumber
  330.  
  331.     ; convert long to a string
  332.     move.l    d1,-(sp)
  333.     pea    _longfmt
  334.     move.l    #_fstrbuf,-(sp)
  335.     jsr    _sprintf
  336.     add.l    #12,sp
  337.  
  338.     lea    _fstrbuf,a0
  339.     move.l    _filenum,d0
  340.     jsr    _writestring    ; write to file
  341.  
  342.     rts
  343.  
  344. ;
  345. ; write a single-precision value to a file. d0=filenumber; d1=FFP value.
  346. ;
  347. _writesingle:
  348.     move.l    d0,_filenum    ; save filenumber
  349.  
  350.     ; convert FFP to a string
  351.     move.l    d1,-(sp)    ; FFP value    
  352.     jsr    _strsingle
  353.     addq    #4,sp
  354.     move.l    d0,a0        ; fnumbuf string address        
  355.  
  356.     cmpi.b    #32,(a0)
  357.     bne.s    _write_ffp_str
  358.     adda.l    #1,a0        ; if ffp string starts with space -> ignore it
  359.  
  360. _write_ffp_str:
  361.     move.l    _filenum,d0    ; d0=filenumber; a0=string
  362.     jsr    _writestring    ; write to file
  363.  
  364.     rts
  365.  
  366. ;
  367. ; PRINT # - write a short integer to a file. d0=short integer; d1=filenumber. 
  368. ;
  369. _fprintshort:
  370.     ; save filenumber.
  371.     move.l    d1,_filenum
  372.     
  373.     ; convert short to string +/- leading space.
  374.     lea    _fstrbuf,a0
  375.     jsr    _strshort    ; a0=string.
  376.  
  377.     ; write the string: d0=filenumber; a0=string.
  378.     move.l    _filenum,d0    
  379.     jsr    _writestring
  380.  
  381.     rts
  382.  
  383. ;
  384. ; PRINT # - write a long integer to a file. d0=long integer; d1=filenumber. 
  385. ;
  386. _fprintlong:
  387.     ; save filenumber.
  388.     move.l    d1,_filenum
  389.     
  390.     ; convert long to string +/- leading space.
  391.     lea    _fstrbuf,a0
  392.     jsr    _strlong    ; a0=string.
  393.  
  394.     ; write the string: d0=filenumber; a0=string.
  395.     move.l    _filenum,d0    
  396.     jsr    _writestring
  397.  
  398.     rts
  399.  
  400. ;
  401. ; PRINT # - write a FFP value to a file. d0=FFP value; d1=filenumber. 
  402. ;
  403. _fprintsingle:
  404.     ; save filenumber.
  405.     move.l    d1,_filenum
  406.     
  407.     ; convert FFP to string +/- leading space.
  408.     move.l    d0,-(sp)
  409.     jsr    _strsingle    ; a0=string.
  410.     addq    #4,sp
  411.     move.l    d0,a0
  412.  
  413.     ; write the string: d0=filenumber; a0=string.
  414.     move.l    _filenum,d0    
  415.     jsr    _writestring
  416.  
  417.     rts
  418.         
  419. ;
  420. ; write a string to a file. d0=filenumber; a0=string.
  421. ;
  422. _writestring:
  423.     jsr    _gencheckfilenum
  424.     cmpi.l    #-1,d0
  425.     bne.s    _writestring_gethandlestore
  426.     moveq    #0,d0        
  427.     rts
  428.  
  429. _writestring_gethandlestore:
  430.     lsl.l    #2,d0        ; filenumber x 4.        
  431.     move.l    #_file_handle_list,d4
  432.     add.l    d0,d4          ; find start of long in list
  433.     move.l    d4,a3
  434.     cmpi.l    #0,(a3)
  435.     bne.s    _write_the_string ; if file handle is used -> continue
  436.     move.l    #BFN,_error_code
  437.     rts
  438.  
  439. _write_the_string:
  440.     move.l    _DOSBase,a6
  441.     move.l    (a3),d1        ; file handle
  442.     move.l    a0,d2        ; string address
  443.     move.l    a0,a2
  444.     jsr    _strlen
  445.     cmpi.l    #0,d0
  446.     bne.s    _do_writestring
  447.     addq.l    #1,d0        ; allow CHR$(0)!!! (some prgs use this)
  448. _do_writestring:
  449.     move.l    d0,d3        ; length of string
  450.     jsr    _LVOWrite(a6)
  451.     jsr    _IoErr_poll
  452.     
  453.     rts
  454.  
  455. ;
  456. ; write a comma to delimit items. d0=filenumber. 
  457. ;
  458. _writecomma:
  459.     jsr    _gencheckfilenum
  460.     cmpi.l    #-1,d0
  461.     bne.s    _writecomma_gethandlestore
  462.     moveq    #0,d0
  463.     rts
  464.  
  465. _writecomma_gethandlestore:
  466.     lsl.l    #2,d0        ; filenumber x 4.        
  467.     move.l    #_file_handle_list,d4
  468.     add.l    d0,d4        ; find start of long in list
  469.     move.l    d4,a3
  470.     cmpi.l    #0,(a3)
  471.     bne.s    _write_the_comma ; if file handle is used -> continue
  472.     move.l    #BFN,_error_code
  473.     rts
  474.  
  475. _write_the_comma:
  476.     move.l    _DOSBase,a6
  477.     move.l    (a3),d1        ; file handle
  478.     move.l    #_comma,d2    ; string address
  479.     moveq    #1,d3        ; length of string
  480.     jsr    _LVOWrite(a6)
  481.     jsr    _IoErr_poll
  482.         
  483.     rts
  484.  
  485. ;
  486. ; write a quotation mark (") to a file to signal the start or end of a string. 
  487. ; d0=filenumber. 
  488. ;
  489. _writequote:
  490.     jsr    _gencheckfilenum
  491.     cmpi.l    #-1,d0
  492.     bne.s    _writequote_gethandlestore
  493.     moveq    #0,d0
  494.     rts
  495.  
  496. _writequote_gethandlestore:
  497.     lsl.l    #2,d0        ; filenumber x 4.        
  498.     move.l    #_file_handle_list,d4
  499.     add.l    d0,d4        ; find start of long in list
  500.     move.l    d4,a3
  501.     cmpi.l    #0,(a3)
  502.     bne.s    _write_the_quote ; if file handle is used -> continue
  503.     move.l    #BFN,_error_code
  504.     rts
  505.  
  506. _write_the_quote:
  507.     move.l    _DOSBase,a6
  508.     move.l    (a3),d1        ; file handle
  509.     move.l    #_quote_mark,d2    ; string address
  510.     moveq    #1,d3        ; length of string
  511.     jsr    _LVOWrite(a6)
  512.     jsr    _IoErr_poll
  513.         
  514.     rts
  515.  
  516. ;
  517. ; write a LF to a file to signal eoln. d0=filenumber. 
  518. ;
  519. _write_eoln:
  520.     jsr    _gencheckfilenum
  521.     cmpi.l    #-1,d0
  522.     bne.s    _write_eoln_gethandlestore
  523.     moveq    #0,d0
  524.     rts
  525.  
  526. _write_eoln_gethandlestore:
  527.     lsl.l    #2,d0        ; filenumber x 4.        
  528.     move.l    #_file_handle_list,d4
  529.     add.l    d0,d4         ; find start of long in list
  530.     move.l    d4,a3
  531.     cmpi.l    #0,(a3)
  532.     bne.s    _write_the_eoln  ; if file handle is used -> continue
  533.     move.l    #BFN,_error_code
  534.     rts
  535.  
  536. _write_the_eoln:
  537.     move.l    _DOSBase,a6
  538.     move.l    (a3),d1        ; file handle
  539.     move.l    #_line_end,d2    ; string address
  540.     move.l    #1,d3        ; length of string
  541.     jsr    _LVOWrite(a6)
  542.     jsr    _IoErr_poll
  543.         
  544.     rts
  545.  
  546. ;
  547. ; write a space to a file. d0=filenumber. 
  548. ;
  549. _writeSPC:
  550.     jsr    _gencheckfilenum
  551.     cmpi.l    #-1,d0
  552.     bne.s    _writeSPC_gethandlestore
  553.     moveq    #0,d0
  554.     rts
  555.  
  556. _writeSPC_gethandlestore:
  557.     lsl.l    #2,d0        ; filenumber x 4.        
  558.     move.l    #_file_handle_list,d4
  559.     add.l    d0,d4        ; find start of long in list
  560.     move.l    d4,a3
  561.     cmpi.l    #0,(a3)
  562.     bne.s    _write_the_SPC ; if file handle is used -> continue
  563.     move.l    #BFN,_error_code
  564.     rts
  565.  
  566. _write_the_SPC:
  567.     move.l    _DOSBase,a6
  568.     move.l    (a3),d1        ; file handle
  569.     move.l    #_space,d2    ; string address
  570.     moveq    #1,d3        ; length of string
  571.     jsr    _LVOWrite(a6)
  572.     jsr    _IoErr_poll
  573.         
  574.     rts
  575.  
  576. ;
  577. ; write a TAB to a file. d0=filenumber. 
  578. ;
  579. _writeTAB:
  580.     jsr    _gencheckfilenum
  581.     cmpi.l    #-1,d0
  582.     bne.s    _writeTAB_gethandlestore
  583.     moveq    #0,d0
  584.     rts
  585.  
  586. _writeTAB_gethandlestore:
  587.     lsl.l    #2,d0        ; filenumber x 4.        
  588.     move.l    #_file_handle_list,d4
  589.     add.l    d0,d4        ; find start of long in list
  590.     move.l    d4,a3
  591.     cmpi.l    #0,(a3)
  592.     bne.s    _write_the_TAB ; if file handle is used -> continue
  593.     move.l    #BFN,_error_code
  594.     rts
  595.  
  596. _write_the_TAB:
  597.     move.l    _DOSBase,a6
  598.     move.l    (a3),d1        ; file handle
  599.     move.l    #_tab,d2    ; string address
  600.     moveq    #2,d3        ; length of string
  601.     jsr    _LVOWrite(a6)
  602.     jsr    _IoErr_poll
  603.         
  604.     rts
  605.  
  606. ;
  607. ; INPUT$(X,[#]filenumber) - input X characters from a file.
  608. ;              - d1=X, d0=filenumber.
  609. ;
  610. _inputstrfromfile:
  611.     ; get address of buffer.
  612.     lea    _fileinpstring,a0    ; this means a 32K limit!!!
  613.  
  614.     ; ++d1 -> fgetchars() returns n-1 characters.
  615.     addq    #1,d1
  616.  
  617.     ; is X reasonable (ie: X > 0) ?
  618.     ; (X should have no upper limit since INPUT$ 
  619.     ;  may be used to read a whole file).
  620.     cmpi.l    #0,d1
  621.     bgt.s    _filenumcheck_inputstrfromfile    
  622.  
  623.     move.b    #0,(a0)
  624.     rts                ; X <= 0? -> return NULL string.
  625.  
  626. _filenumcheck_inputstrfromfile:
  627.     ; legal file number?
  628.     jsr    _gencheckfilenum
  629.     cmpi.l    #-1,d0
  630.     bne.s    _inputstrfromfile_get_handle
  631.  
  632.     move.b    #0,(a0)
  633.     rts                ; return NULL string.
  634.  
  635. _inputstrfromfile_get_handle:
  636.     lsl.l    #2,d0            ; filenumber x 4.        
  637.     move.l    #_file_handle_list,d4
  638.     add.l    d0,d4             ; find start of long in list.
  639.     move.l    d4,a3
  640.     cmpi.l    #0,(a3)
  641.     bne.s    _do_inputstrfromfile      ; if file handle is used -> continue.
  642.  
  643.     move.b    #0,(a0)
  644.     move.l    #BFN,_error_code
  645.     rts                ; return NULL string.
  646.  
  647. _do_inputstrfromfile:
  648.     ; call fgetchars() -- (see fgets.c)
  649.     move.l    (a3),-(sp)        ; push the filehandle.
  650.     move.l    d1,-(sp)        ; push max_chars to read.
  651.     move.l    a0,-(sp)        ; push buffer address.
  652.     jsr    _fgetchars        ; returns X chars or NULL string.
  653.     add.l    #12,sp
  654.     jsr    _IoErr_poll
  655.  
  656.     move.l    #_fileinpstring,d0
  657.  
  658.     rts
  659.  
  660. ;
  661. ; LINE INPUT #filenumber;string-variable - read a line from filenumber'th file. 
  662. ;                     - d0=filenumber, a0=string-variable.
  663. ;
  664. _line_input:
  665.     ; legal file number?
  666.     jsr    _gencheckfilenum
  667.     cmpi.l    #-1,d0
  668.     bne.s    _line_input_get_handle
  669.  
  670.     move.b    #0,(a0)
  671.     rts                ; return NULL string.
  672.  
  673. _line_input_get_handle:
  674.     lsl.l    #2,d0            ; filenumber x 4.        
  675.     move.l    #_file_handle_list,d4
  676.     add.l    d0,d4             ; find start of long in list.
  677.     move.l    d4,a3
  678.     cmpi.l    #0,(a3)
  679.     bne.s    _do_line_input      ; if file handle is used -> continue.
  680.  
  681.     move.b    #0,(a0)
  682.     move.l    #BFN,_error_code
  683.     rts                ; return NULL string.
  684.  
  685. _do_line_input:
  686.     ; call fgetline() -- (see fgets.c)
  687.     move.l    (a3),-(sp)        ; push the filehandle.
  688.     move.l    #MAXSTRINGSIZE,-(sp)    ; want to read MAXSTRINGSIZE-1 chars. 
  689.     move.l    a0,-(sp)        ; push buffer address.
  690.     jsr    _fgetline        ; returns line of chars or NULL string.
  691.     add.l    #12,sp
  692.     jsr    _IoErr_poll
  693.     rts
  694.  
  695. ;
  696. ; INPUT# - input a string from a file. d0=filenumber; a0=temporary string.
  697. ;
  698. _finputstring:
  699.     ; store string address.
  700.     move.l    a0,-(sp)
  701.  
  702.     ; legal file number?
  703.     jsr    _gencheckfilenum
  704.     cmpi.l    #-1,d0
  705.     bne.s    _finputstring_get_handle
  706.  
  707.     move.b    #0,(a0)
  708.     addq    #4,sp            ; pop string address
  709.     rts                ; return NULL string.
  710.  
  711. _finputstring_get_handle:
  712.     lsl.l    #2,d0            ; filenumber x 4.        
  713.     move.l    #_file_handle_list,d4
  714.     add.l    d0,d4             ; find start of long in list.
  715.     move.l    d4,a3
  716.     cmpi.l    #0,(a3)
  717.     bne.s    _do_finputstring      ; if file handle is used -> continue.
  718.  
  719.     move.b    #0,(a0)
  720.     addq    #4,sp            ; pop string address
  721.  
  722.     move.l    #BFN,_error_code
  723.     rts                ; return NULL string.
  724.  
  725. _do_finputstring:
  726.     move.l    (a3),-(sp)        ; push file handle.
  727.     move.l    #MAXSTRINGSIZE,-(sp)    ; want to read MAXSTRINGSIZE-1 chars.
  728.     move.l    a0,-(sp)        ; push temp string address.
  729.     jsr    _fgetseqfld        ; returns sequential field in string.
  730.     add.l    #12,sp            
  731.     jsr    _IoErr_poll
  732.     move.l    (sp)+,a0        ; return string start address.
  733.  
  734.     rts    
  735.  
  736. ;
  737. ; INPUT# - input a FFP value from a file. d0=filenumber; a0=temporary string.
  738. ;      - FFP value returned in d0.
  739. ;
  740. _finputsingle:
  741.     jsr    _finputstring
  742.     move.l    a0,-(sp)
  743.     jsr    _val
  744.     addq    #4,sp
  745.     rts
  746.     
  747. ;
  748. ; INPUT# - input a short integer from a file. d0=filenumber; a0=temp string.
  749. ;      - short integer value returned in d0.
  750. ;
  751. _finputshort:
  752.     jsr    _finputstring
  753.     move.l    a0,-(sp)
  754.     jsr    _short_from_string
  755.     addq    #4,sp
  756.     rts
  757.  
  758. ;
  759. ; INPUT# - input a long integer from a file. d0=filenumber; a0=temp string.
  760. ;      - long integer value returned in d0.
  761. ;
  762. _finputlong:
  763.     jsr    _finputstring
  764.     move.l    a0,-(sp)
  765.     jsr    _long_from_string
  766.     addq    #4,sp
  767.     rts
  768.  
  769. ;
  770. ; EOF(n) - d0=n=filenumber. returns -1 if EOF reached, and 0 if not (d0).
  771. ;
  772. _eoftest:
  773.     jsr    _gencheckfilenum
  774.     cmpi.l    #-1,d0
  775.     bne.s    _eof_get_handle
  776.     rts            ; return TRUE
  777.     
  778. _eof_get_handle:
  779.     lsl.l    #2,d0        ; filenumber x 4.        
  780.     move.l    #_file_handle_list,d4
  781.     add.l    d0,d4        ; find start of long in list
  782.     move.l    d4,a0
  783.     move.l    d4,_eofhandle    ; store file handle
  784.     cmpi.l    #0,(a0)
  785.     bne.s    _do_eof_test    ; if file handle is used -> continue
  786.  
  787.     moveq    #-1,d0        ; unused file number, so return TRUE
  788.     move.l    #BFN,_error_code
  789.     rts
  790.  
  791. _do_eof_test:
  792.     move.l     (a0),d1        ; file handle
  793.     move.l     #1,d2        ; seek 1 byte from...
  794.     move.l    #0,d3        ; current position
  795.     move.l    _DOSBase,a6
  796.     jsr    _LVOSeek(a6)
  797.  
  798.      cmpi.l    #-1,d0        ; -1 = seek error
  799.     bne.s    _lastfileposn    
  800.     
  801.     rts            ; return TRUE (EOF reached)
  802.  
  803. _lastfileposn:
  804.     ; return to pre-seek position
  805.     move.l    _eofhandle,a0
  806.     move.l     (a0),d1        ; file handle
  807.     move.l     #-1,d2        ; seek -1 bytes from...
  808.     move.l    #0,d3        ; current position
  809.     move.l    _DOSBase,a6
  810.     jsr    _LVOSeek(a6)
  811.     
  812.     moveq    #0,d0                 
  813.     rts            ; return FALSE
  814.  
  815. ;
  816. ; LOF(n) - returns the length of an opened file in d0. n=d0=file number. 
  817. ;
  818. _lof:
  819.     jsr    _gencheckfilenum
  820.     cmpi.l    #-1,d0
  821.     bne.s    _lof_get_handle
  822.     moveq    #0,d0
  823.     rts            ; return length of 0
  824.  
  825. _lof_get_handle:
  826.     lsl.l    #2,d0        ; filenumber x 4.            
  827.     move.l    #_file_handle_list,d4
  828.     add.l    d0,d4        ; find start of long in list
  829.     move.l    d4,a0
  830.     cmpi.l    #0,(a0)
  831.     bne.s    _get_lof    ; if file handle is used -> continue
  832.     moveq    #0,d0        ; unused file number, so return length=0.
  833.     move.l    #BFN,_error_code
  834.     rts
  835.  
  836. _get_lof:
  837.     move.l    (a0),_filehandle
  838.     movea.l    _DOSBase,a6
  839.  
  840.     ; seek 0 bytes from EOF
  841.     ; to get old position in file.
  842.     move.l    _filehandle,d1
  843.     moveq    #0,d2
  844.     move.l    #OFFSET_END,d3
  845.     jsr    _LVOSeek(a6)
  846.     move.l    d0,_oldfilepos    ; store file position before LOF(n) called.
  847.  
  848.     ; seek 0 bytes from EOF again
  849.     ; because the first time the old 
  850.     ; position was returned. 
  851.     move.l    _filehandle,d1
  852.     moveq    #0,d2
  853.     move.l    #OFFSET_END,d3
  854.     jsr    _LVOSeek(a6)
  855.     move.l    d0,_filesize    ; store the file length.
  856.  
  857.     ; now return to the position
  858.     ; in the file prior to the above
  859.     ; two seeks.
  860.     move.l    _filehandle,d1
  861.     move.l    _oldfilepos,d2
  862.     move.l    #OFFSET_BEGINNING,d3
  863.     jsr    _LVOSeek(a6)
  864.  
  865.     move.l    _filesize,d0    ; return length of file in d0.
  866.  
  867.     rts
  868.     
  869. ;
  870. ; HANDLE(n) - returns the file handle of the nth file number. d0=n.
  871. ;
  872. _handle:
  873.     jsr    _gencheckfilenum
  874.     cmpi.l    #-1,d0
  875.     bne.s    _retrieve_handle
  876.     moveq    #0,d0
  877.     rts            ; return 0
  878.  
  879. _retrieve_handle:
  880.     lsl.l    #2,d0        ; filenumber x 4.        
  881.     move.l    #_file_handle_list,d4
  882.     add.l    d0,d4         ; find start of long in list
  883.     movea.l    d4,a0
  884.     move.l    (a0),d0        ; d0=filehandle
  885.  
  886.     rts
  887.  
  888. ;
  889. ; Check for legal filenumber.     Return -1 in d0 if not in range 0..254,
  890. ;                 otherwise just return filenumber.
  891. ;
  892. _gencheckfilenum:
  893.     subi.l    #1,d0        ; 1..255 -> 0..254
  894.  
  895.     ; check whether within bounds
  896.     cmpi.l    #0,d0
  897.     bge.s    _gencheckhifilenum
  898.     moveq    #-1,d0        ; return -1 for non-existent file.
  899.     move.l    #BFN,_error_code
  900.     rts            ; filenumber < 0? -> exit
  901.  
  902. _gencheckhifilenum:
  903.     cmpi.l    #254,d0
  904.     ble.s    _exitgencheckfilenum
  905.     moveq    #-1,d0        ; return -1 for non-existent file.
  906.     move.l    #BFN,_error_code
  907.  
  908. _exitgencheckfilenum:
  909.     rts            
  910.  
  911. ;
  912. ; KILL <filespec> - deletes file(s) or directory(ies).
  913. ;          - d1 = filespec.
  914. ;
  915. _kill:
  916.     movea.l    _DOSBase,a6
  917.     jsr    _LVODeleteFile(a6)
  918.     jsr    _IoErr_poll
  919.     rts
  920.  
  921. ;
  922. ; NAME <filespec1> AS <filespec2> - renames a file or directory.
  923. ;                  - d1 = filespec1, d2 = filespec2.
  924. ;
  925. _rename:
  926.     movea.l    _DOSBase,a6
  927.     jsr    _LVORename(a6)
  928.     jsr    _IoErr_poll
  929.     rts
  930.  
  931. ;
  932. ; CHDIR <dirname> - changes current directory to <dirname>.
  933. ;          - d1 = dirname.
  934. ;
  935. _chdir:
  936.     ; get a read lock on dirname (d1)
  937.     movea.l    _DOSBase,a6
  938.     move.l    #ACCESS_READ,d2
  939.     jsr    _LVOLock(a6)
  940.     jsr    _IoErr_poll
  941.  
  942.     tst.l    d0
  943.     beq.s    _quitchdir    ; quit if requested lock is zero
  944.  
  945.     ; change directory
  946.     move.l    d0,d1        ; pass lock in d1
  947.     jsr    _LVOCurrentDir(a6)
  948.  
  949.     tst.l    d0
  950.     beq.s    _quitchdir    ; quit if old lock is zero
  951.  
  952.     ; free old lock
  953.     move.l    d0,d1
  954.     jsr    _LVOUnLock(a6)
  955.  
  956. _quitchdir:        
  957.     rts
  958.  
  959.     END
  960.  
  961.